/**
 * 
 */
package mapmaker.network;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import mapmaker.config.Config;
import mapmaker.robot.engine.DifferentialDriveProperties;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;


public final class NetworkCommunication {

	private NetworkCommunication(){}

	/**
	 * Retrieve the position of the robot from server
	 * @return a JSONObject representing the position 
	 */
	public final static JSONObject getRobotPositionFromServer(){
		HttpClient client = new DefaultHttpClient();
		HttpGet getRequest = new HttpGet(Config.SERVER_URL_LOCALIZATION);
		JSONObject obj = null;
		while(obj == null){
			try {
				HttpResponse response = client.execute(getRequest);
				String json = EntityUtils.toString(response.getEntity());
				obj = (JSONObject) JSONSerializer.toJSON(json);
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return obj;
	}

	/**
	 * Retrieve the differential drive information from the server 
	 * @return a JSONObject representing these informations
	 */
	public final static JSONObject getRobotDifferentialDriveFromServer(){
		HttpClient client = new DefaultHttpClient();
		HttpGet getRequest = new HttpGet(Config.SERVER_URL_DIFFERENTIAL_DRIVE);
		JSONObject obj = null;
		while(obj == null){
			try {
				HttpResponse response = client.execute(getRequest);
				String json = EntityUtils.toString(response.getEntity());
				obj = (JSONObject) JSONSerializer.toJSON(json);
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return obj;
	}

	/**
	 * Retrieve the lasers echoes from server
	 * @return a JSONObject representing echoes
	 */
	public final static JSONObject getRobotLaserEchoesFromServer(){
		HttpClient client = new DefaultHttpClient();
		HttpGet getRequest = new HttpGet(Config.SERVER_URL_LASERS_ECHOES);
		JSONObject obj = null;
		while(obj == null){
			try {
				HttpResponse response = client.execute(getRequest);
				String json = EntityUtils.toString(response.getEntity());
				obj = (JSONObject) JSONSerializer.toJSON(json);
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return obj;
	}

	/**
	 * Retrieve laser properties from server
	 * @return a JSONObject representing laser properties
	 */
	public final static JSONObject getRobotLaserPropertiesFromServer(){
		HttpClient client = new DefaultHttpClient();
		HttpGet getRequest = new HttpGet(Config.SERVER_URL_LASERS_PROPERTIES);
		JSONObject obj = null;
		while(obj == null){
			try {
				HttpResponse response = client.execute(getRequest);
				String json = EntityUtils.toString(response.getEntity());
				obj = (JSONObject) JSONSerializer.toJSON(json);
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return obj;
	}

	/**
	 * Send new parameters of angular and linear speed to server
	 * @param obj the command of differential drive converted in JSON
	 */
	public static final void postSpeedToServer(JSONObject obj){
		HttpClient client = new DefaultHttpClient();
		HttpPost postRequest = new HttpPost(Config.SERVER_URL_DIFFERENTIAL_DRIVE);
		postRequest.setHeader("Content-type", "application/json");
		postRequest.setHeader("Accept", "text/json");
		StringEntity jsonString;
		boolean recieved = false;
		while(!recieved){
			try {
				jsonString = new StringEntity(obj.toString());
				postRequest.setEntity(jsonString);
				HttpResponse response = client.execute(postRequest);
				if(response.getStatusLine().getStatusCode() == 204){
					recieved = true;
				//	Log.i(LOG_TAG, "POST SPEED  : AngularSpeed : " + obj.getDouble("TargetAngularSpeed") + " , LinearSpeed : " +  obj.getDouble("TargetLinearSpeed") );
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Initialize the differential drive properties from server
	 * @return The differential drive properties as an Object 
	 */
	public static final DifferentialDriveProperties initDifferentialDrivePropertiesFromServer(){
		HttpClient client = new DefaultHttpClient();
		HttpGet getRequest = new HttpGet(Config.SERVER_URL_DIFFERENTIAL_DRIVE);
		JSONObject obj = null;
		while(obj == null){
			try {
				HttpResponse response = client.execute(getRequest);
				String json = EntityUtils.toString(response.getEntity());
				obj = (JSONObject) JSONSerializer.toJSON(json);
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return new DifferentialDriveProperties(obj.getJSONObject("Properties").getInt("MaxAngularAcceleration")
				, obj.getJSONObject("Properties").getInt("MaxAngularSpeed")
				, obj.getJSONObject("Properties").getInt("MinAngularSpeed")
				, obj.getJSONObject("Properties").getInt("MaxAngularDeceleration")
				, obj.getJSONObject("Properties").getInt("MaxLinearAcceleration")
				, obj.getJSONObject("Properties").getInt("MaxLinearDeceleration")
				, obj.getJSONObject("Properties").getInt("MaxLinearSpeed")
				, obj.getJSONObject("Properties").getInt("MinLinearSpeed")
				, obj.getJSONObject("Properties").getDouble("Width"));
	}
}

